package com.wonders.bigdata.utils;

import com.aspose.words.*;
import com.aspose.words.Document;
import com.aspose.words.Paragraph;
import com.aspose.words.Section;
import com.aspose.words.Shape;
import com.itextpdf.text.*;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.apache.poi.util.IOUtils;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.junit.Assert;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.MalformedURLException;

public class AsposeDoc2Pdf {
    private static String separator = File.separator;//文件夹路径分格符

    public static void main(String[] args) throws Exception {
        String imageFile = "/file/logo.png";
        String wordFile = "/file/f367e7b4-231d-4435-a3bb-dcd2e0cad204.docx";
        String file = "/file/f367e7b4-231d-4435-a3bb-dcd2e0cad204.pdf";
        String text = "新冠疫苗研发才打完本编号生成计划稳步惊魂未定";
        doc2pdf(wordFile, file);
        //System.out.println(converDocx2Pdf(wordFile));
        //addWotermarkImagToPdf(file, imageFile);
        //addWotermarkTextToPdf(file, text);

    }

    /**
     * pdf添加水印图片
     * @param file /file/file.pdf
     * @param imageFile /file/logo.png
     * @throws Exception
     */
    private static void addWotermarkImagToPdf(String file, String imageFile) throws Exception {
        PdfReader reader = null;
        PdfStamper stamper = null;
        try {
            reader = new PdfReader(new FileInputStream(file));
            stamper = new PdfStamper(reader, new FileOutputStream(file));
            int pageNo = reader.getNumberOfPages();
            // image watermark
            Image img = Image.getInstance(IOUtils.toByteArray(new FileInputStream(imageFile)));
            float w = Math.min(img.getScaledWidth(), 460);
            float h = Math.min(img.getScaledHeight(), 300);
            for (float f : img.matrix()) {
                System.out.println(f);
            }
            // transparency
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.1f);
            // properties
            PdfContentByte over;
            Rectangle pagesize;
            float x, y;
            // loop over every page
            for (int i = 1; i <= pageNo; i++) {
                pagesize = reader.getPageSizeWithRotation(i);
                x = (pagesize.getLeft() + pagesize.getRight()) / 2;
                y = (pagesize.getTop() + pagesize.getBottom()) / 2;
                over = stamper.getOverContent(i);
                over.saveState();
                over.setGState(gs);
                System.out.println(w + ", " + h + ", " + (x - (w / 2)) + ", " + (y - (h / 2)));
//				617.0, 400.0, -10.839996, 220.95999
                over.addImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2));
                over.restoreState();
            }
            if (stamper != null) {
                stamper.close();
            }
        } catch (FileNotFoundException e) {
            throw new Exception("FileNotFoundException", e);
        } catch (BadElementException e) {
            throw new Exception("BadElementException", e);
        } catch (MalformedURLException e) {
            throw new Exception("MalformedURLException", e);
        } catch (IOException e) {
            throw new Exception("IOException", e);
        } catch (DocumentException e) {
            throw new Exception("DocumentException", e);
        } finally {
            if (reader!=null) {
                reader.close();
            }
        }
    }

    /**
     * pdf添加文字水印
     * @param file /file/file.pdf
     * @param waterMarkName
     * @throws Exception
     */
    private static void addWotermarkTextToPdf(String file, String waterMarkName) throws Exception {
        PdfReader reader = null;
        PdfStamper stamper = null;
        try {
            reader = new PdfReader(new FileInputStream(file));
            stamper = new PdfStamper(reader, new FileOutputStream(file));
            //添加铺满文字水印
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            Rectangle pageRect = null;
            // transparency
            PdfGState gs = new PdfGState();
            // 这里是透明度设置
            gs.setFillOpacity(0.1f);
            // 这里是条纹不透明度
            //gs.setStrokeOpacity(0.4f);
            int total = reader.getNumberOfPages() + 1;

            JLabel label = new JLabel();
            FontMetrics metrics;
            int textH = 0;
            int textW = 0;
            label.setText(waterMarkName);
            metrics = label.getFontMetrics(label.getFont());
            textH = metrics.getHeight();// 字符串的高，只和字体有关
            textW = metrics.stringWidth(label.getText());// 字符串的宽

            PdfContentByte under;
            // 循环给每一张pdf添加水印
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                under = stamper.getOverContent(i);// 在内容上方添加水印
                under.saveState();
                under.setGState(gs);
                under.beginText();
                //under.setColorFill(BaseColor.PINK);  //添加文字颜色  不能动态改变 放弃使用
                under.setFontAndSize(base, 36);

                //水印文字成30度角倾斜
                //你可以随心所欲的改你自己想要的角度
                for (int height = textH; height < pageRect.getHeight(); height = height + textH*15) {
                    for (int width = textW; width < pageRect.getWidth() + textW; width = width + textW*2) {
                        // rotation:倾斜角度
                        float x = width - textW;// 水印横坐标
                        float y = height - textH;// 水印纵坐标
                        under.showTextAligned(Element.ALIGN_LEFT,waterMarkName, x, y, 45);
                        System.out.println("水印坐标：x=" + x + " y=" + y);
                    }
                }
                // 添加水印文字
                under.endText();
            }
            System.out.println("添加水印成功！");
            if (stamper != null) {
                stamper.close();
            }
        } catch (FileNotFoundException e) {
            throw new Exception("FileNotFoundException", e);
        } catch (BadElementException e) {
            throw new Exception("BadElementException", e);
        } catch (MalformedURLException e) {
            throw new Exception("MalformedURLException", e);
        } catch (IOException e) {
            throw new Exception("IOException", e);
        } catch (DocumentException e) {
            throw new Exception("DocumentException", e);
        } finally {
            if (reader!=null) {
                reader.close();
            }
        }
    }

    public static boolean getLicense() throws Exception {
        boolean result = false;
        try {

            InputStream is = com.aspose.words.Document.class
                    .getResourceAsStream("/com.aspose.words.lic_2999.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return result;
    }

    public static void doc2pdf(String inPath, String outPath) throws Exception {
        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档有水印
            throw new Exception("com.aspose.words lic ERROR!");
        }

        System.out.println("aspose开始转化 -> " + inPath + " -> " + outPath);

        try {
            long old = System.currentTimeMillis();
            File file = new File(outPath);
            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(inPath); // word文档
            // 支持RTF HTML,OpenDocument, PDF,EPUB, XPS转换
            doc.save(os, SaveFormat.PDF);
            os.close();
            long now = System.currentTimeMillis();
            System.out.println("convert OK! " + ((now - old) / 1000.0) + "秒");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *  仅支持docx文件转换成pdf且耗时比较长
     * inPath ：原文档路径   outPath： 要生产的pdf路径  imgUrl ：水印图片路径
     */
    public static void docToPdfWatermark(String inPath,String outPath,String imgUrl) throws Exception {
        // 验证License 若不验证则转化出的pdf文档会有产品信息的水印产生
        if (getLicense()) {
            try {
                FileOutputStream os = new FileOutputStream(new File(outPath));
                Document doc = new Document(inPath);
                Assert.assertNull(doc.getBackgroundShape());
                Shape shapeRectangle = new Shape(doc, ShapeType.RECTANGLE);
                doc.setBackgroundShape(shapeRectangle);
                //添加水印图片
                shapeRectangle.getImageData().setImage(imgUrl);
                Assert.assertTrue(doc.getBackgroundShape().hasImage());
                //降低对比度，增加亮度
                /*shapeRectangle.getImageData().setContrast(0.2);
                shapeRectangle.getImageData().setBrightness(0.7);*/
                //文字水印内容
                Shape watermark  = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT);
                watermark.getTextPath().setText("文字水印");
                //水印字体
                watermark.getTextPath().setFontFamily("宋体");
                //水印宽度
                watermark.setWidth(500);
                //水印高度
                watermark.setHeight(100);
                //旋转水印
                watermark.setRotation(-40);
                //水印颜色
                watermark.getFill().setColor(Color.lightGray);
                watermark.setStrokeColor(Color.lightGray);

                watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
                watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
                watermark.setWrapType(WrapType.NONE);
                watermark.setVerticalAlignment(VerticalAlignment.CENTER);
                watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);

                Paragraph watermarkPara = new Paragraph(doc);
                watermarkPara.appendChild(watermark);

                for (Section sect : doc.getSections()){
                    insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
                    insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST);
                    insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN);
                }
                doc.save(os, SaveFormat.PDF);
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    private static void insertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, int headerType) throws Exception {
        HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType);

        if (header == null) {
            header = new HeaderFooter(sect.getDocument(), headerType);
            sect.getHeadersFooters().add(header);
        }

        header.appendChild(watermarkPara.deepClone(true));
    }

    /**
     * word转pdf
     * @param wordPath word文件路径
     * @return 生成的pdf路径
     */
    public static String converDocx2Pdf(String wordPath) {
        OutputStream os = null;
        InputStream is = null;
        try {
            is = new FileInputStream(new File(wordPath));
            WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);
            Mapper fontMapper = new IdentityPlusMapper();
            fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
            fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
            fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
            fontMapper.put("黑体", PhysicalFonts.get("SimHei"));
            fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
            fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
            fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
            fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
            fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
            fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
            fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
            fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
            fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
            fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
            mlPackage.setFontMapper(fontMapper);

            //输出pdf文件路径和名称
            String fileName = "pdfNoMark_" + System.currentTimeMillis() + ".pdf";
            String pdfNoMarkPath = "/file" + separator + fileName;
            os = new java.io.FileOutputStream(pdfNoMarkPath);
            //docx4j  docx转pdf
            FOSettings foSettings = Docx4J.createFOSettings();
            foSettings.setWmlPackage(mlPackage);
            Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
            is.close();//关闭输入流
            os.close();//关闭输出流
            return pdfNoMarkPath;
        }catch (Exception e) {
            e.printStackTrace();
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
        return "";
    }
}